package com.demo.gateway.filter;


import cn.hutool.json.JSONUtil;
import com.demo.common.core.exception.ResponseErrorCode;
import com.demo.common.core.response.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.regex.Pattern;
import static com.alibaba.nacos.common.http.param.MediaType.APPLICATION_JSON;

/**
 * 全局拦截器，作用所有的微服务
 * 1. 对请求头中参数进行处理 2. 重写StripPrefix = 1,支持全局
 */
@Slf4j
@Component
public class RequestGlobalFilter implements GlobalFilter, Ordered {


    // 拦截路径的正则表达式 (匹配 /*/internal/**)
    private static final Pattern INTERNAL_PATH_PATTERN =
            Pattern.compile("^/[^/]+/internal(/.*)?$");

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求路径
        String path = exchange.getRequest().getPath().value();

        // 检查路径是否匹配拦截规则
        if (isInternalPath(path)) {
            return handleBlockedRequest(exchange);
        }

        return chain.filter(exchange);
    }

    /**
     * 判断路径是否应被拦截
     */
    private boolean isInternalPath(String path) {
        return INTERNAL_PATH_PATTERN.matcher(path).matches();
    }

    /**
     * 处理被拦截的请求
     */
    private Mono<Void> handleBlockedRequest(ServerWebExchange exchange) {
        exchange.getResponse().setStatusCode(HttpStatus.OK);
        exchange.getResponse().getHeaders().add(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON);
        Response<Object> response = Response.fail(ResponseErrorCode.FORBIDDEN);
        String responseBody = JSONUtil.toJsonStr(response);
        return exchange.getResponse()
                .writeWith(Mono.just(exchange.getResponse()
                        .bufferFactory()
                        .wrap(responseBody.getBytes())));
    }

    /**
     * 设置过滤器执行顺序 (数字越小优先级越高)
     * 设置为最高优先级保证最先执行
     */
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }


}
